package net.atomarrow.db.tx;

import java.lang.reflect.Method;

import net.atomarrow.annotation.Inject;
import net.atomarrow.annotation.Priority;
import net.atomarrow.aop.ServiceInterceptor;
import net.atomarrow.db.annotation.Transaction;
import net.atomarrow.ioc.ActionContext;
@Priority(-1)
public class TransactionInterceptor implements ServiceInterceptor{

	@Inject
	private TransactionConfig transactionConfig;

	@Override
	public void beforeAction(Object obj, Method method, Object[] args) {
		ActionContext context = ActionContext.getContext();
		context.push(method);
		if(context.isNeedCheckTransaction()){
			context.setNeedCheckTransaction(false);
			boolean needTx=whetherNeedTx(method);
			context.setNeedTx(needTx);
		}
	}

	private boolean whetherNeedTx(Method method) {
		if(method.isAnnotationPresent(Transaction.class)){
			return true;
		}
		String methodName=method.getName();
		for(String prefix:transactionConfig.getNeedTxPrefixs()){
			if(methodName.startsWith(prefix)){
				return true;
			}
		}
		return false;
	}


	@Override
	public void afterAction(Object obj, Method method, Object[] args,Object result,Throwable error) {
		ActionContext context = ActionContext.getContext();
		if(error!=null){
			context.setNeedRollback(true);
		}
		context.pop();
		if(context.isNeedCheckTransaction()){
            if(context.isNeedTx()){
                if(context.isNeedRollback()){
                    context.rollback();
                }else{
                    context.commitTx();
                }
            }
		}
	}
}
